import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'

Vue.use(VueRouter)

const routes = [
  {
    path: '/', // 网页打开后第一次默认路由路径就是 '/'
    // 下面一行是设置默认路由为 /login ，意为打开后默认页面为登录页
    // 下面一行是设置默认打开直接显示布局页面(layout组件)
    component: () => import('@/views/layout'),
    redirect: '/home', // redirect的作用是重新定向，会导致路由规则重新匹配，这一整套路由规则是：一打开网页，默认路由路径为 / ，然后重新定向为 /home ，再重新匹配路由规则，根据二级路由路径 home ，显示对应的路由组件
    children: [
      // 侧边栏导航，点击会切换路由地址，路由地址是靠通过接口向后台请求数据回来再铺设上去的，所以你的路由规则要与它配合
      {
        path: 'home',
        component: () => import('@/views/home')
      },
      {
        path: 'user-info',
        component: () => import('@/views/user/userInfo.vue')
      },
      {
        path: 'user-avatar',
        component: () => import('@/views/user/userAvatar.vue')
      },
      {
        path: 'user-pwd',
        component: () => import('@/views/user/userPwd.vue')
      },
      {
        path: 'art-cate',
        component: () => import('@/views/article/artCate.vue')
      },
      {
        path: 'art-list',
        component: () => import('@/views/article/artList.vue')
      }
    ]
  },
  {
    path: '/reg',
    // 这里的设置了路由规则，当页签地址添加了跳转内容reg时，router就返回组件register
    // 也可以在上面直接import引入需要的路由组件，然后在下面直接用，而不是用箭头函数
    component: () => import('@/views/register') // 这里是运用了一个箭头函数，import引入并return返回这个register组件，由于是箭头函数，就可以将return省略
    // webpack提供的import函数来路由懒加载导入组件
    // 路由懒加载，就是页面路由路径切换到 /reg，才去加载对应组件代码
    // 好处：让首页加载文件体积更新，打开更快
  },
  {
    path: '/login',
    component: () => import('@/views/login')
  }
]

const router = new VueRouter({
  routes
})

const whiteList = ['/login', '/reg'] // 白名单，里面装的是无需登录就可以访问的路由地址

// 全局前置路由守卫
// 下面这个函数会在每次路由相互之间进行跳转之前调用(浏览器第一次打开项目页面时也会触发这个全局前置路由守卫)，初始化的时候也会被调用，next()如果强制切换路由地址，会再次走路由守卫，再去匹配路由表
router.beforeEach((to, from, next) => {
  const token = store.state.token
  // 登录了
  if (token) {
    if (!store.state.userInfo.username) { // 这个条件判断是查看vuex中是否有token值和用户名这个信息，如果有token值并且没有username，那么就去获取用户信息，这样当登录成功进入主页后，vuex中有了token和userInfo用户信息，vue就不会在去获取用户信息了，到退出登录，就会执行清除用户信息和token值的操作，这样登陆时就会再执行获取用户信息的操作
      // 这个条件判断的作用：因为退出登录时会清空token值，而退出登录也算是页面跳转，所以下面的代码也会执行，这样没有了token值，却执行下面的代码，就会报错，所以得判断本地是否有token值
      store.dispatch('getUserInfoActions') // 在组件相互之间进行跳转之前执行这些代码
    }
    next() // 只有调用了next()方法，路由才会放行，代码才会执行下一步，让目标组件显示
  } else {
    // 未登录
    // includes()：判断指定值是否在指定数组中出现国，出现过的话返回true
    if (whiteList.includes(to.path)) { // 判断whiteList数组中是否包含当前要切换到的路由地址
      next() // 走到这一步说明用户未登录，但访问的路由地址在whiteList中出现过，所以这里执行next()
    } else { // 这里是未登录，并且要前往的路由地址不在whiteList数组中
      // 利用next强制切换到登录路径上
      next('/login')
    }
  }
})

export default router
